//
//
//  @ Project : AgriMarketSystem
//  @ Date : 18/10/2013
//  @ Author : NTT
//
//

using System;
using System.Collections.Generic;
using System.Linq;
namespace AgriMarketService
{
    public class Auction
    {
        protected int auctionId;
        public int AuctionId
        {
            get { return auctionId; }
            set { auctionId = value; }
        }
        DateTime postedDate;

        public DateTime PostedDate
        {
            get { return postedDate; }
            set { postedDate = value; }
        }
        protected string topic;

        public string Topic
        {
            get { return topic; }
            set { topic = value; }
        }
        //protected int productId;
        //public int ProductId
        //{
        //    get { return productId; }
        //    set { productId = value; }
        //}

        private Product product;

        public Product Product
        {
            get { return product; }
            set { product = value; }
        }

        protected decimal initialPrice;

        public decimal InitialPrice
        {
            get { return initialPrice; }
            set { initialPrice = value; }
        }
        protected string productDescription;

        public string ProductDescription
        {
            get { return productDescription; }
            set { productDescription = value; }
        }
        protected DateTime startedDate;

        public DateTime StartedDate
        {
            get { return startedDate; }
            set { startedDate = value; }
        }
        protected DateTime finishedDate;

        public DateTime FinishedDate
        {
            get { return finishedDate; }
            set { finishedDate = value; }
        }

        private byte[] productImageBytes;

        public byte[] ProductImageBytes
        {
            get { return productImageBytes; }
            set { productImageBytes = value; }
        }
        protected string productImage;
        public string ProductImage
        {
            get { return productImage; }
            set { productImage = value; }
        }

        protected string authorId;

        public string AuthorId
        {
            get { return authorId; }
            set { authorId = value; }
        }

        //private UserAccount author;

        //public UserAccount Author
        //{
        //    get { return author; }
        //    set { author = value; }
        //}

        protected TypeOfAuction type;

        public TypeOfAuction Type
        {
            get { return type; }
            set { type = value; }
        }

        int isSentEmail = 0;

        public int IsSentEmail
        {
            get { return isSentEmail; }
            set { isSentEmail = value; }
        }
        public Auction() { }
        public Auction(int auctionId,
            DateTime postedDate,
            string topic,
            //int productId,
            Product product,
            decimal initialPrice,
            string productDescription,
            DateTime startedDate,
            DateTime finishedDate,
            string productImage,
            string authorId,
            //UserAccount author,
            TypeOfAuction type) 
        {
            this.auctionId = auctionId;
            this.postedDate = postedDate;
            this.topic = topic;
            //this.productId = productId;
            this.product = product;
            this.initialPrice = initialPrice;
            this.productDescription = productDescription;
            this.startedDate = startedDate;
            this.finishedDate = finishedDate;
            this.productImage = productImage;
            this.ProductDescription = productDescription;
            this.authorId = authorId;
            //this.author = author;
            this.type = type;
        }
        public Auction(int auctionId,
          DateTime postedDate,
          string topic,
          //int productId,
           Product product,
          decimal initialPrice,
          string productDescription,
          DateTime startedDate,
          DateTime finishedDate,
            byte[] productImageBytes,
          string productImage,
          string authorId,
            //UserAccount author,
          TypeOfAuction type)
        {
            this.auctionId = auctionId;
            this.postedDate = postedDate;
            this.topic = topic;
            //this.productId = productId;
            this.product = product;
            this.initialPrice = initialPrice;
            this.productDescription = productDescription;
            this.startedDate = startedDate;
            this.finishedDate = finishedDate;
            this.productImageBytes = productImageBytes;
            this.productImage = productImage;
            this.ProductDescription = productDescription;
            this.authorId = authorId;
            //this.author = author;
            this.type = type;
        }
        public static int AddNew(Auction newAuction)
        {
            Tbl_Auction newTbl_Auction = newAuction.ToTbl_Auction();
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            db.Tbl_Auctions.InsertOnSubmit(newTbl_Auction);
            try
            {
                db.SubmitChanges();
                newAuction.auctionId = newTbl_Auction.AuctionId;

                string[] splittedProductImage = newTbl_Auction.ProductImage.Split('.');
                newTbl_Auction.ProductImage = "Images/Auctions/"+newTbl_Auction.AuctionId.ToString() + "." + splittedProductImage[splittedProductImage.Length-1];
                FileProvider.Upload(newAuction.productImageBytes, newTbl_Auction.ProductImage);
                Tbl_Auction updatedTbl_Auction = (from tempTbl_Auction in db.Tbl_Auctions
                                                  where tempTbl_Auction.AuctionId == newAuction.AuctionId
                                                  select tempTbl_Auction).FirstOrDefault();
                updatedTbl_Auction.ProductImage = newTbl_Auction.ProductImage;
                db.SubmitChanges();
                return newAuction.auctionId;
            }
            catch (Exception e)
            {
                return -1;//error
            }
        }
        public static int Update(Auction updatedAuction)
        {

            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            Tbl_Auction updatedTbl_Auction = (from tempTbl_Auction in db.Tbl_Auctions
                                                            where tempTbl_Auction.AuctionId == updatedAuction.AuctionId
                                                            select tempTbl_Auction).FirstOrDefault();
            if (updatedTbl_Auction == null)
                return -1;//no exist
            updatedTbl_Auction.AuctionId = updatedAuction.auctionId;
            updatedTbl_Auction.Topic = updatedAuction.topic;
            updatedTbl_Auction.ProductId = updatedAuction.product.ProductId;
            updatedTbl_Auction.InitialPrice = updatedAuction.initialPrice;
            updatedTbl_Auction.ProductDescription = updatedAuction.productDescription;
            updatedTbl_Auction.StartedDate = updatedAuction.startedDate;
            updatedTbl_Auction.FinishedDate = updatedAuction.finishedDate;
            updatedTbl_Auction.ProductImage = updatedAuction.productImage;
            updatedTbl_Auction.AuthorId = updatedAuction.authorId;
            updatedTbl_Auction.TypeId = updatedAuction.type.TypeId;
            if (updatedAuction.productImageBytes != null)
            {
                if (!FileProvider.Upload(updatedAuction.productImageBytes, updatedAuction.productImage))
                    return 1;
            }
            try
            {
                db.SubmitChanges();
                return 0;
            }
            catch (Exception e)
            {
                return 1;//error
            }
        }
        public static int DeleteByAuctionId(int deletedAuctionId)
        {
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            Tbl_Auction deletedTbl_Auction = (from tempTbl_Auction in db.Tbl_Auctions
                                                            where tempTbl_Auction.AuctionId == deletedAuctionId
                                                            select tempTbl_Auction).FirstOrDefault();
            if (deletedTbl_Auction == null)
                return -1; //no exist
            if (!Auctioneer.DeleteAuctioneersByAuctionId(deletedAuctionId))
                return 1;//error
            if (!FollowedAuction.DeleteFollowedAuctionsByAuctionId(deletedAuctionId))
                return 1;
            var auctionSentEmails = (from temp in db.Tbl_AuctionSentEmails
                                     where temp.AuctionId == deletedAuctionId
                                     select temp
                                       );
            db.Tbl_AuctionSentEmails.DeleteAllOnSubmit(auctionSentEmails);
            try
            {
                db.SubmitChanges();
                db.Tbl_Auctions.DeleteOnSubmit(deletedTbl_Auction);
                FileProvider.Delete(deletedTbl_Auction.ProductImage);
                db.SubmitChanges();
                return 0;
            }
            catch
            {
                return 1;//error
            }
            
        }
        public static List<Auction> GetAllUnfinishedAuctions()
        {
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            List<Auction> result = (from tempAuction in db.Tbl_Auctions
                                    where tempAuction.FinishedDate > DateTime.Now
                                    select new Auction(tempAuction.AuctionId,
                                        tempAuction.PostedDate,
                                        tempAuction.Topic,
                                        Product.GetProductById(tempAuction.ProductId),
                                        tempAuction.InitialPrice,
                                        tempAuction.ProductDescription,
                                        tempAuction.StartedDate,
                                        tempAuction.FinishedDate,
                                        tempAuction.ProductImage,
                                        tempAuction.AuthorId,
                                        TypeOfAuction.GetTypeById(tempAuction.TypeId)
                                        )).ToList();
            return result;
        }
        public static Auction GetAuctionById(int auctionId) {
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            Auction result = (from tempAuction in db.Tbl_Auctions
                                    where tempAuction.AuctionId==auctionId
                                    select new Auction(tempAuction.AuctionId,
                                        tempAuction.PostedDate,
                                        tempAuction.Topic,
                                        Product.GetProductById(tempAuction.ProductId),
                                        tempAuction.InitialPrice,
                                        tempAuction.ProductDescription,
                                        tempAuction.StartedDate,
                                        tempAuction.FinishedDate,
                                        tempAuction.ProductImage,
                                        tempAuction.AuthorId,
                                        TypeOfAuction.GetTypeById(tempAuction.TypeId)
                                        )).FirstOrDefault();
            return result;
        }
        public Tbl_Auction ToTbl_Auction()
        {
            return new Tbl_Auction()
            {
               AuctionId=this.AuctionId,
               PostedDate=this.PostedDate,
               Topic=this.Topic,
               ProductId=this.Product.ProductId,
               InitialPrice=this.InitialPrice,
               ProductDescription=this.ProductDescription,
               StartedDate=this.StartedDate,
               FinishedDate=this.FinishedDate,
               ProductImage=this.ProductImage,
               AuthorId=this.authorId,
               TypeId=this.Type.TypeId
            };
        }
        public static List<Auction> SearchFor(string content){
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            List<Auction> result = (from tempAuction in db.Tbl_Auctions
                                    where  tempAuction.AuthorId.Contains(content) || tempAuction.ProductDescription.Contains(content) ||tempAuction.Topic.Contains(content)
                                    select new Auction(tempAuction.AuctionId,
                                        tempAuction.PostedDate,
                                        tempAuction.Topic,
                                        Product.GetProductById(tempAuction.ProductId),
                                        tempAuction.InitialPrice,
                                        tempAuction.ProductDescription,
                                        tempAuction.StartedDate,
                                        tempAuction.FinishedDate,
                                        tempAuction.ProductImage,
                                        tempAuction.AuthorId,
                                        TypeOfAuction.GetTypeById(tempAuction.TypeId)
                                        )).ToList();
            return result;
        }
        public static List<Auction> GetUnSentAuctions()
        {
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            List<Auction> finishedAuctions = (from auction in db.Tbl_Auctions
                                                  where auction.FinishedDate < DateTime.Now && !db.Tbl_AuctionSentEmails.Any(a => a.AuctionId == auction.AuctionId) && db.Tbl_Auctioneers.Any(a=>a.AuctionId==auction.AuctionId)
                                                  select new Auction(auction.AuctionId,
                                        auction.PostedDate,
                                        auction.Topic,
                                        Product.GetProductById(auction.ProductId),
                                        auction.InitialPrice,
                                        auction.ProductDescription,
                                        auction.StartedDate,
                                        auction.FinishedDate,
                                        auction.ProductImage,
                                        auction.AuthorId,
                                        TypeOfAuction.GetTypeById(auction.TypeId)
                                        )
                                               ).ToList();
            
            return finishedAuctions;
        }
        public static List<Auction> GetBeingAuctions()
        {
            AgriMarketDataClassesDataContext db = new AgriMarketDataClassesDataContext();
            List<Auction> result = (from tempAuction in db.Tbl_Auctions
                                    where tempAuction.FinishedDate > DateTime.Now && tempAuction.StartedDate <= DateTime.Now
                                    select new Auction(tempAuction.AuctionId,
                                        tempAuction.PostedDate,
                                        tempAuction.Topic,
                                        Product.GetProductById(tempAuction.ProductId),
                                        tempAuction.InitialPrice,
                                        tempAuction.ProductDescription,
                                        tempAuction.StartedDate,
                                        tempAuction.FinishedDate,
                                        tempAuction.ProductImage,
                                        tempAuction.AuthorId,
                                        TypeOfAuction.GetTypeById(tempAuction.TypeId)
                                        )).ToList();
            return result;
        }
    }
}